﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YinLongTool.Ui
{
    public class AppReportManagerEx
    {
        public static readonly AppReportManagerEx Instance = new AppReportManagerEx();
        private readonly Dictionary<Type, Delegate> _delegates = new Dictionary<Type, Delegate>();

        private AppReportManagerEx()
        {
        }
        public void AddListener<T>(Action<T> listener) where T : EventArgs
        {
            if (this._delegates.TryGetValue(typeof(T), out var a))
            {
                this._delegates[typeof(T)] = Delegate.Combine(a, listener);
            }
            else
            {
                this._delegates[typeof(T)] = listener;
            }
        }
        public void AddListener<T, Tout>(Func<T, Tout> listener) where T : EventArgs
        {
            if (this._delegates.TryGetValue(typeof(T), out var a))
            {
                this._delegates[typeof(T)] = Delegate.Combine(a, listener);
            }
            else
            {
                this._delegates[typeof(T)] = listener;
            }
        }
        public void RemoveListener<T >(Action<T> listener) where T : EventArgs
        {
            if (this._delegates.TryGetValue(typeof(T), out var source))
            {
                Delegate @delegate = Delegate.Remove(source, listener);
                if (@delegate == null)
                {
                    this._delegates.Remove(typeof(T));
                }
                else
                {
                    this._delegates[typeof(T)] = @delegate;
                }
            }
        }
        public void RemoveListener<T, Tout>(Func<T, Tout> listener) where T : EventArgs
        {
            if (this._delegates.TryGetValue(typeof(T), out var source))
            {
                Delegate @delegate = Delegate.Remove(source, listener);
                if (@delegate == null)
                {
                    this._delegates.Remove(typeof(T));
                }
                else
                {
                    this._delegates[typeof(T)] = @delegate;
                }
            }
        }
        public void Send<T>(T e) where T : EventArgs
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }
            if (this._delegates.TryGetValue(typeof(T), out var d))
            {
                var eventDelegate = d as Action<T>;
                eventDelegate.Invoke(e);
            }
           
        }
        public Tout Send<T, Tout>(T e) where T : EventArgs
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }
            if (this._delegates.TryGetValue(typeof(T), out var d))
            {
                var eventDelegate = d as Func<T, Tout>;
                return eventDelegate.Invoke(e);
            }
            return default;
        }
    }
}
